/*
    3D Office Environment
    Copyright (C) 2011  Till Merker

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#ifndef BASEOFFICESCENE_H
#define BASEOFFICESCENE_H

#include <Ogre.h>
#include "globals.h"
#include "OfficeEnv.h"

using namespace Ogre;

namespace OfficeEnv {

class BaseOfficeScene {
    
    private:	
	/* Checks if the user is looking at a desktop. If so, sets mTargetedDesktop and highlights it */
	void targetDesktop();

    protected:
	/* OGRE */
	Root *mRoot;
	SceneManager *mSceneMgr;
	Camera *mCamera;
	
	/* Holds current camera orientation */
	Radian mYaw, mPitch;
	
	/* Used to store original camera position/orientation when zooming in */
	Vector3 mCameraPos;
	Quaternion mCameraOrient;
		
	/* what is "Up" for this scene */
	Vector3 mUp;

	/* Size of screen */
	int mWidth, mHeight;
	
	int mNumDesktops;
	
	/* Size of desktop entity in scene */
	int mDeskEntWidth, mDeskEntHeight;
		
	/* Nodes/Entities for desktops and their frames */
	SceneNode *mDesktopNode[MAX_DESKTOPS];
	Entity *mDesktopEnt[MAX_DESKTOPS];
	Entity *mFrameEnt[MAX_DESKTOPS];
	
	/* Index of desktop currently being targeted */
	int mTargetedDesktop;	
	
	/* Animation that is currently executed */
	CameraAnimation mCurrentAnimation;
	
	/* Total number of frames in the current animation */
	int mAnimFrames;
	
	/* Start/endpoint of the current animation */
	Vector3 mAnimPosStart;
	Vector3 mAnimPosEnd;
	
	/* Camera-Orientation of start/end of animation as well as 2 points inbetween */
	Quaternion mAnimOrientStart;
	Quaternion mAnimOrientA;
	Quaternion mAnimOrientB;
	Quaternion mAnimOrientEnd;	

	/* Current frame in animation */
	int mAnimCurrentFrame;

	/* Pure virtual functions to be implemented in the derived Scene classes */
	
	/* Create scene manager  */
	virtual SceneManager *createSceneManager() = 0;
	/* Load scene from file */
	virtual void loadScene(String sceneFile) = 0;
	/* Create a desktop entity and its parent node */
	virtual void getDesktopEntity(int desktopIndex, SceneNode **node, Entity **entity) = 0;
	/* Return "Up"-direction of the scene */	
	virtual Vector3 getUpVector() = 0;
	/* Move camera to the specified position, if possible */
	virtual void moveTo(Vector3 dest) = 0;
	/* Glue a vector to the "ground" of the scene */
	virtual void glueToGround(Vector3 &pos) = 0;
	/* Get Min/Max pitch when looking up/down */
	virtual void getPitchLimits(Radian &minPitch, Radian &maxPitch) = 0;
	
    public:	
	BaseOfficeScene() : mRoot(0), mTargetedDesktop(-1), mCurrentAnimation(CA_None) {};
	virtual ~BaseOfficeScene();
	
	/* Initialize the scene object */
	virtual void init(Root *root, int width, int height, int numDesktops, String sceneFile);
	
	Camera *getCamera() { return mCamera; }
	
	/* Processes an input action. forward/sidestep should be either +1 ior -1, 
	 * yaw and pitch are delta values in radians */ 
	void inputAction(int forward, int sidestep, float yaw, float pitch);
	
	/* Returns the desktop the user is currently looking at, -1 if none  */
	int getTargetedDesktop() { return mTargetedDesktop; }
	
	void startAnimation(CameraAnimation animation, int param);
	CameraAnimation getCurrentAnimation() { return mCurrentAnimation; }
	
	/* Step the current animation forward by one frame */
	void updateAnimation();
};

}

#endif